package com.weixin.project.Service;

import com.weixin.project.Common.Enum.ModuleType;
import com.weixin.project.Common.Exception.EntityNotExistException;
import com.weixin.project.Config.Config;
import com.weixin.project.Dao.DanmuDao;
import com.weixin.project.Dao.UserFavVideoDao;
import com.weixin.project.Dao.VideoDao;
import com.weixin.project.Entity.Danmu;
import com.weixin.project.Entity.UserFavVideo;
import com.weixin.project.Entity.Video;
import com.weixin.project.Specification.VideoSpecification;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;

@Service
public class VideoService {
    @Value("10")
    Integer pageSize;
    @Value("${document.imagePath}")
    String uploadPath;
    @Autowired
    VideoDao videoDao;
    @Autowired
    DanmuDao danmuDao;
    @Autowired
    UserFavVideoDao userFavVideoDao;
    @Autowired
    OSSService ossService;
    public Video storeVideo(Video video){
        return videoDao.save(video);
    }

    public Video findVideo(Integer id){
        Optional<Video> videoOp = videoDao.findById(id);
        if (!videoOp.isPresent()) throw new EntityNotExistException("video", id);
        return videoOp.isPresent()?videoOp.get():videoOp.get();
    }

    public Danmu storeDanmu(Danmu danmu) {
        return danmuDao.save(danmu);
    }

    public List<Danmu> findAllDanmuOfVideo(Integer videoId){
        return danmuDao.getDanmusByVideoId(videoId);
    }

    /**
     * 收藏/取消收藏
     * @param userId user自增Id
     * @param videoId videoId
     */
    public void userFavoriteVideo(Integer userId, Integer videoId){
        UserFavVideo fav = userFavVideoDao.getUserFavVideoByUserIdAndAndVideoId(userId, videoId);
        if (fav == null) {
            UserFavVideo userFavVideo = new UserFavVideo();
            userFavVideo.setUserId(userId);
            userFavVideo.setVideoId(videoId);
            userFavVideoDao.save(userFavVideo);
        }
        else{
            userFavVideoDao.delete(fav);
        }
    }

    /**
     * 用户是否收藏了某个视频
     * @param userId 用户Id
     * @param videoId 视频Id
     * @return 是否收藏
     */
    public boolean isFavorite(Integer userId, Integer videoId){
        UserFavVideo fav = userFavVideoDao.getUserFavVideoByUserIdAndAndVideoId(userId, videoId);
        return fav == null? false:true;
    }

    public Integer countDanmusOfVideo(Integer videoId){
        return danmuDao.countDanmusByVideoId(videoId);
    }

    @Transactional
    public void incOpenCount(Integer videoId) {
        Optional<Video> videoOptional = videoDao.findById(videoId);
        if (!videoOptional.isPresent()) return;
        Video video = videoOptional.get();
        video.setOpenCount(video.getOpenCount() + 1);
        videoDao.save(video);
    }

    public Integer countFavoritesOfVideo(Integer videoId){
        return userFavVideoDao.countUserFavVideosByVideoId(videoId);
    }

    public Page<Video> findAllVideos(Integer page){
        Sort sort = Sort.by("id").ascending();
        Pageable pageable = PageRequest.of(page, pageSize, sort);
        Page<Video> videoPage = videoDao.findAll(pageable);
        return videoPage;
    }

    public List<Video> findVideosOfUser(Integer userId){
        return videoDao.getVideosByUserId(userId);
    }

    public void deleteVideo(Video video){
        ossService.deleteFile(video.getVideoSrc());
        ossService.deleteFile(video.getCoverSrc());
        videoDao.delete(video);
        List<UserFavVideo> favs = userFavVideoDao.getUserFavVideosByVideoId(video.getId());
        for (UserFavVideo fav: favs) userFavVideoDao.delete(fav);
    }

    public Page<UserFavVideo> findFavVideosOfUser(Integer userId, Integer page) {
        Sort sort = Sort.by("id").ascending();
        Pageable pageable = PageRequest.of(page, pageSize, sort);
        return userFavVideoDao.getUserFavVideosByUserId(userId, pageable);
    }

    public Integer countAllVideos(){
        return Math.toIntExact(videoDao.count());
    }

    public Integer countOriginVideosOfUser(Integer userId){
        return videoDao.countVideosByUserId(userId);
    }

    public Integer countFavVideosOfUser(Integer userId){
        return userFavVideoDao.countUserFavVideosByUserId(userId);
    }

    public List<Video> searchVideos(String text){
        return videoDao.findAll(VideoSpecification.titleContains(text));
    }

    public List<Video> findVideosByModule(ModuleType moduleType){
        return videoDao.getVideosByModule(moduleType);
    }
}
